package main

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"
	"log"

	"golang.org/x/sys/windows"
)

// 打开指定进程的句柄
func openProcessHandle(pid uint32) (windows.Handle, error) {
	handle, err := windows.OpenProcess(windows.SYNCHRONIZE, false, pid)
	if err != nil {
		return 0, err
	}
	return handle, nil
}

// 等待进程关闭事件
func waitForProcessExit(handle windows.Handle) error {
	event, err := windows.WaitForSingleObject(handle, windows.INFINITE)
	if err != nil {
		return fmt.Errorf("等待进程关闭时出错: %w", err)
	}
	if event == windows.WAIT_OBJECT_0 {
		return nil // 进程关闭
	}
	return fmt.Errorf("unexpected wait result: %d", event)
}

// 重新运行当前程序
func restartSelf() error {
	// 获取当前程序路径
	executable, err := os.Executable()
	if err != nil {
		return fmt.Errorf("获取程序路径失败: %w", err)
	}

	// 创建新进程
	cmd := exec.Command(executable) // 使用当前程序路径重新启动
	cmd.Stdout = os.Stdout          // 继承父进程输出
	cmd.Stderr = os.Stderr          // 继承父进程错误输出

	// 启动新进程
	err = cmd.Start()
	if err != nil {
		return fmt.Errorf("重新启动程序失败: %w", err)
	}

	fmt.Printf("重新启动程序成功，PID=%d\n", cmd.Process.Pid)
	return nil
}

func main() {
	// 处理退出信号
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-sigChan
		fmt.Println("接收到退出信号，准备重新运行自身程序...")
		if err := restartSelf(); err != nil {
			fmt.Printf("重新运行失败: %v\n", err)
		}
		os.Exit(0)
	}()

	pid := os.Getpid()
	fmt.Printf("当前进程 PID: %d\n", pid)
	// 替换为你要监听的进程 PID
	targetPid := uint32(pid)

	handle, err := openProcessHandle(targetPid)
	if err != nil {
		fmt.Printf("无法打开进程句柄: %v\n", err)
		os.Exit(1)
	}
	defer windows.CloseHandle(handle)

	fmt.Printf("正在监听 PID=%d 的关闭事件...\n", targetPid)

	// 启动监听
	err = waitForProcessExit(handle)
	if err != nil {
		fmt.Printf("监听过程中出错: %v\n", err)
	} else {
		fmt.Println("目标进程已关闭，准备重新运行自身程序...")
		// 重新启动自身程序
		if err := restartSelf(); err != nil {
			fmt.Printf("重新运行失败: %v\n", err)
		}
	}

	// 循环输出日志到当前程序目录下的log.txt文件
	for {
		time.Sleep(1 * time.Second)
		log.Println("当前时间: ", time.Now().Format("2006-01-02 15:04:05"))
	}
}
